<?php
/*********************************************
 *  CPG Dragonfly™ CMS
 *********************************************
	Copyright © since 2010 by CPG-Nuke Dev Team
	http://dragonflycms.org

	Dragonfly is released under the terms and conditions
	of the GNU GPL version 2 or any later version

	$Source$
	$Revision$
	$Author$
	$Date$
**********************************************/

# PECL
if (!defined('UUID_TYPE_DEFAULT')) { define('UUID_TYPE_DEFAULT', 0); }
if (!defined('UUID_TYPE_TIME'))    { define('UUID_TYPE_TIME',    1); } # v1
if (!defined('UUID_TYPE_DCE'))     { define('UUID_TYPE_DCE',     2); }
if (!defined('UUID_TYPE_NAME'))    { define('UUID_TYPE_NAME',    3); }
if (!defined('UUID_TYPE_RANDOM'))  { define('UUID_TYPE_RANDOM',  4); } # v4

abstract class Poodle_UUID
{
	const
		TYPE_DEFAULT = UUID_TYPE_DEFAULT,
		TYPE_TIME    = UUID_TYPE_TIME,
		TYPE_DCE     = UUID_TYPE_DCE,
		TYPE_NAME    = UUID_TYPE_NAME,
		TYPE_RANDOM  = UUID_TYPE_RANDOM;

	public static function generate($mode = self::TYPE_DEFAULT)
	{
		# OSSP
		if (function_exists('uuid_make'))
		{
			$modes = array(UUID_MAKE_V1, UUID_MAKE_V3, UUID_MAKE_V4, UUID_MAKE_V5, UUID_MAKE_MC);
			uuid_create(&$v1);
			foreach ($modes as $mode) { if (uuid_make($v1, UUID_MAKE_V1)) { break; } }
			if (is_resource($v1)) {
				uuid_export($v1, UUID_FMT_STR, &$uuid);
				if (!preg_match('#^[0\-]*$#',$uuid)) { return $uuid; }
			}
		}

		# PECL
		else if (function_exists('uuid_create')){ return uuid_create($mode); }

		# COM/Windows
		if (function_exists('com_create_guid')) { return trim(com_create_guid(), '{}'); }

		# Fallback if none is available
		$uuid = md5(microtime().getmypid()); # this should be random enough for now
		# set variant and version fields for 'true' random uuid
		$uuid[12] = '4';
		$hex = '0123456789abcdef';
		$uuid[16] = $hex[(8 + (ord($uuid[16]) & 3))];
		# return formated uuid
		return substr($uuid,  0, 8).'-'
			.  substr($uuid,  8, 4).'-'
			.  substr($uuid, 12, 4).'-'
			.  substr($uuid, 16, 4).'-'
			.  substr($uuid, 20);
	}

	public static function time()   { return self::generate(self::TYPE_TIME); }

	public static function random() { return self::generate(self::TYPE_RANDOM); }

}
